package com.zmn.plat.business.impl.orderconfig.track;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.plat.business.interfaces.orderconfig.track.OrderTrackBService;
import com.zmn.plat.common.dictionary.PlatErrorCodeDict;
import com.zmn.plat.common.dto.orderconfig.track.OrderTrackDIO;
import com.zmn.plat.common.dto.orderconfig.track.OrderTrackDRO;
import com.zmn.plat.common.dto.orderconfig.track.OrderTrackReasonDRO;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.model.entity.orderconfig.track.OrderTrack;
import com.zmn.plat.model.entity.orderconfig.track.OrderTrackQuery;
import com.zmn.plat.model.entity.orderconfig.track.category.OrderTrackCategory;
import com.zmn.plat.model.entity.orderconfig.track.reason.OrderTrackReason;
import com.zmn.plat.model.vo.orderconfig.track.OrderTrackVO;
import com.zmn.plat.services.interfaces.orderconfig.track.OrderTrackService;
import com.zmn.plat.services.interfaces.orderconfig.track.category.OrderTrackCategoryService;
import com.zmn.plat.services.interfaces.orderconfig.track.reason.OrderTrackReasonService;
import com.zmn.plat.utils.bean.BeanCopyUtils;

/**
 * @author tanbiao
 * @description
 * @modifier
 * @since 2020/11/19 18:12
 **/
@Service
public class OrderTrackBServiceImpl implements OrderTrackBService {
    @Resource
    private OrderTrackService orderTrackService;
    @Resource
    private OrderTrackReasonService orderTrackReasonService;
    @Resource
    private OrderTrackCategoryService orderTrackCategoryService;

    @Override
    public OrderTrackVO getById(Integer trackId) {
        if (Objects.isNull(trackId)) {
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL);
        }

        OrderTrack track = orderTrackService.findByKey(trackId);
        if (Objects.isNull(track)) {
            return null;
        }

        OrderTrackVO vo = new OrderTrackVO();
        BeanUtils.copyProperties(track, vo);
        List<OrderTrackReason> reasons = orderTrackReasonService.listByKeys(StringUtil.convertStrsToList(vo.getTrackReason()));
        if (!CollectionUtils.isEmpty(reasons)) {
            List<String> reasonList = reasons.stream().map(e -> e.getReason()).collect(Collectors.toList());
            vo.setTrackReasonStr(reasonList.stream().collect(Collectors.joining(",")));
            vo.setTrackReasonList(reasons);
        }

        OrderTrackCategory category = orderTrackCategoryService.findByKey(track.getCategId());

        if (Objects.nonNull(category)) {
            vo.setCategName(category.getCategName());
        }

        return vo;
    }

    @Override
    public OrderTrackDRO getByTrackId(Integer trackId) {
        OrderTrackVO orderTrackVO = this.getById(trackId);
        if (Objects.isNull(orderTrackVO)) {
            return null;
        }

        // 对数据进行转换
        OrderTrackDRO dro = new OrderTrackDRO();
        BeanCopyUtils.copyProperties(orderTrackVO, dro);

        List<OrderTrackReason> list = orderTrackVO.getTrackReasonList();
        if (!CollectionUtils.isEmpty(list)) {
            List<OrderTrackReasonDRO> droReasonList = BeanCopyUtils.copyProperties(list, OrderTrackReason.class, OrderTrackReasonDRO.class, OrderTrackReasonDRO::new);
            dro.setTrackReasonList(droReasonList);
        }
        return dro;
    }

    @Override
    public List<OrderTrackDRO> listByTrackIds(List<Integer> trackIds) {
        if (CollectionUtils.isEmpty(trackIds)) {
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL);
        }

        List<OrderTrackVO> trackList = orderTrackService.listByKeys(trackIds);
        if (CollectionUtils.isEmpty(trackList)) {
            return Collections.emptyList();
        }

        List<OrderTrackDRO> list = new ArrayList<>();
        BeanCopier copier = BeanCopier.create(OrderTrackVO.class, OrderTrackDRO.class, false);

        for (OrderTrackVO vo : trackList) {
            OrderTrackDRO target = new OrderTrackDRO();
            copier.copy(vo, target, null);
            List<OrderTrackReason> reasons = orderTrackReasonService.listByKeys(StringUtil.convertStrsToList(vo.getTrackReason()));
            if (!CollectionUtils.isEmpty(reasons)) {
                target.setTrackReasonList(BeanCopyUtils.copyProperties(reasons, OrderTrackReason.class, OrderTrackReasonDRO.class, OrderTrackReasonDRO::new));
            }

            list.add(target);
        }

        return list;
    }

    @Override
    public List<OrderTrackDRO> listByCategIdAndBizType(Integer categId, Integer bizType) {
        OrderTrackQuery query = new OrderTrackQuery();
        query.setCategId(categId);
        query.setBizType(bizType);
        List<OrderTrack> list = orderTrackService.listByQuery(query);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        List<OrderTrackDRO> retList = BeanCopyUtils.copyProperties(list, OrderTrack.class, OrderTrackDRO.class, OrderTrackDRO::new);
        return retList;
    }

    @Override
    public List<OrderTrackDRO> listByDIO(OrderTrackDIO dio) {
        if (Objects.isNull(dio)) {
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL);
        }

        OrderTrackQuery query = new OrderTrackQuery();
        BeanCopyUtils.copyProperties(dio, query);

        List<OrderTrack> list = orderTrackService.listByQuery(query);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }

        return listByTrackIds(list.stream().map(e -> e.getTrackId()).collect(Collectors.toList()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addEdit(OrderTrack track, String operator) {
        checkParam(track);
        OrderTrackQuery query = new OrderTrackQuery();
        query.setTrackContent(track.getTrackContent());
        OrderTrack existsTrack = null;
        List<OrderTrack> trackList = orderTrackService.listByQuery(query);
        if (!CollectionUtils.isEmpty(trackList)) {
            if (trackList.size() > 1) {
                throw new PlatException("跟单内容不能重复");
            }
            existsTrack = trackList.get(0);
        }

        // 新增，
        if (!NumberUtil.isPositiveInteger(track.getTrackId())) {
            if (Objects.nonNull(existsTrack)) {
                throw new PlatException("跟单内容不能重复");
            }
            track.setUpdater(operator);
            track.setCreater(operator);
            orderTrackService.insert(track);
        } else {
            if (Objects.nonNull(existsTrack) && !Objects.equals(existsTrack.getTrackId(), track.getTrackId())) {
                throw new PlatException("跟单内容不能重复");
            }
            track.setUpdater(operator);
            orderTrackService.updateByKey(track);
        }

        return track.getTrackId();
    }

    private void checkParam(OrderTrack track) {
        // 针对二级缘由的校验
        String trackReason = track.getTrackReason();
        if (StringUtil.isBlank(trackReason)) {
            throw new PlatException("跟单缘由参数不合法");
        }
        if (StringUtil.convertStrsToList(trackReason).size() > 10) {
            throw new PlatException("跟单缘由不能超过十个");
        }

        if (NumberUtil.isNullOrZero(track.getLevel()) || NumberUtil.isNullOrZero(track.getLegacy()) || NumberUtil.isNullOrZero(track.getCategId()) || NumberUtil.isNullOrZero(track.getSort())
                || NumberUtil.isNullOrZero(track.getStatus())) {
            throw new PlatException("跟单类型，跟单等级,是否遗留,排序，状态不能为空，请检查");
        }

        if (StringUtil.isBlank(track.getTrackDeptId()) || StringUtil.isBlank(track.getOrderStatus()) || StringUtil.isBlank(track.getBillType()) || StringUtil.isBlank(track.getTrackOperator())
                || StringUtil.isBlank(track.getTrackContent()) || StringUtil.isBlank(track.getBizType())) {
            throw new PlatException("跟单内容，跟单部门,订单状态,单据类型，发起人，业务类型不能为空，请检查");
        }

    }
}
